
package com.ruoyi.busi.contest.service.impl;

import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.ruoyi.busi.contest.domain.*;
import com.ruoyi.busi.contest.domain.dto.*;
import com.ruoyi.busi.contest.mapper.*;
import com.ruoyi.busi.contest.service.IContestService;
import com.ruoyi.common.core.core.domain.AjaxResult;
import com.ruoyi.common.core.utils.PageUtils;
import com.ruoyi.common.orm.core.page.TableDataInfo;

import com.ruoyi.common.security.utils.LoginHelper;
import jakarta.annotation.Resource;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;
/**
 * 大赛主表Service业务层处理
 */
@Slf4j
@Service
public class ContestServiceImpl implements IContestService {
    @Resource
    private ContestMapper contestMapper;
    @Resource
    private CompetitionDetailMapper competitionDetailMapper;
    @Resource
    private CompetitionStageMapper competitionStageMapper; 
    @Resource
    private CompetitionAttachmentMapper competitionAttachmentMapper;
    @Autowired
    ObjectMapper objectMapper;

    /**
     * 查询大赛列表
     */
    @Override
    public List<Contest> selectContestList(Contest contest) {
        PageUtils.startPage();
        List<Contest> contests = contestMapper.selectContestList(contest);
        return contests;
    }

    
    /**
     * 查询大赛(完整信息)
     */
    @Override
    public CompetitionCreateDTO selectContestById(Long id) {
        Contest contest = contestMapper.selectContestById(id);
        if (contest == null) {
            return null;
        }

        CompetitionCreateDTO dto = new CompetitionCreateDTO();
        dto.setId(contest.getId().toString());
        dto.setOrganizationHostname(contest.getOrganizationHostname());
        dto.setTenantId(contest.getTenantId());

        // 设置基础信息
        BasicInfo basicInfo = new BasicInfo();
        basicInfo.setName(contest.getName());
        basicInfo.setTheme(contest.getTheme());
        basicInfo.setType(contest.getType());
        basicInfo.setCompetitionDesc(contest.getCompetitionDesc());
        basicInfo.setLogoUrl(contest.getLogoUrl());
        dto.setBasicInfo(basicInfo);

        // 获取大赛详情
        CompetitionDetail detail = competitionDetailMapper.selectCompetitionDetailByCompetitionId(id);
        if (detail != null) {
            dto.setDetails(detail.getDetails());
        }

        // 获取大赛阶段信息
        List<CompetitionStage> stages = competitionStageMapper.selectCompetitionStagesByCompetitionId(id);
        if (stages != null && !stages.isEmpty()) {
            List<CompetitionStageDTO> stageDTOs = stages.stream()
                .map(stage -> {
                    CompetitionStageDTO stageDTO = new CompetitionStageDTO();
                    stageDTO.setStage(stage.getStageName());
                    stageDTO.setStartTime(stage.getStartTime());
                    stageDTO.setEndTime(stage.getEndTime());
                    return stageDTO;
                })
                .collect(Collectors.toList());
            dto.setCompetitionStages(stageDTOs);
        }

        // 获取附件信息
        List<CompetitionAttachment> attachments = competitionAttachmentMapper.selectByCompetitionId(id);
        if (attachments != null && !attachments.isEmpty()) {
            List<Attachment> attachmentDTOs = attachments.stream()
                .map(attachment -> {
                    Attachment attachmentDTO = new Attachment();
                    attachmentDTO.setFileName(attachment.getFileName());
                    attachmentDTO.setFileType(attachment.getFileType());
                    attachmentDTO.setFileSize(attachment.getFileSize());
                    attachmentDTO.setFileUrl(attachment.getFileUrl());
                    attachmentDTO.setDescription(attachment.getDescription());
                    return attachmentDTO;
                })
                .collect(Collectors.toList());
            dto.setAttachments(attachmentDTOs);
        }

        return dto;
    }

    /**
     * 获取大赛基本信息
     */
    @Override
    public Contest getContestBasicInfo(Long id) {
        Contest contest = contestMapper.selectContestById(id);
        if (contest != null) {
            Contest basicInfo = new Contest();
            basicInfo.setId(contest.getId());
            basicInfo.setName(contest.getName());
            basicInfo.setType(contest.getType());
            basicInfo.setStartTime(contest.getStartTime());
            basicInfo.setEndTime(contest.getEndTime());
            basicInfo.setCompetitionDesc(basicInfo.getCompetitionDesc());
            basicInfo.setOrganizationHostname(contest.getOrganizationHostname());
            basicInfo.setStatus(contest.getStatus());
            basicInfo.setCurrentStage(contest.getCurrentStage());
            basicInfo.setLogoUrl(contest.getLogoUrl());
            basicInfo.setTenantId(contest.getTenantId());
            return basicInfo;
        }
        return null;
    }

    @Override
    @Transactional
    public AjaxResult updateContestStatusAndStage(Long id, Integer status, String currentStage) {
        Contest contest = contestMapper.selectContestById(id);
        if (contest == null) {
            return AjaxResult.error("大赛不存在");
        }
        
        if (status != null) {
            if (status < 0 || status > 2) {
                return AjaxResult.error("状态值不合法");
            }
            contest.setStatus(status);
        }
        
        if (currentStage != null) {
            contest.setCurrentStage(currentStage);
        }
        
        contest.setUpdateBy(LoginHelper.getUsername());
        int result = contestMapper.updateContest(contest);
        return result > 0 ? AjaxResult.success("更新成功") : AjaxResult.error("更新失败");
    }

    @Override
    @Transactional
    public AjaxResult updateCompetition(CompetitionCreateDTO dto) {
        Long competitionId = Long.parseLong(dto.getId());
        try {
            Contest contest = contestMapper.selectContestById(competitionId);
            if (contest == null) {
                return AjaxResult.error("大赛不存在");
            }

            // 更新基础信息
            contest.setName(dto.getBasicInfo().getName());
            contest.setTheme(dto.getBasicInfo().getTheme());
            contest.setType(dto.getBasicInfo().getType());
            contest.setTenantId(LoginHelper.getTenantId());
            
            // 设置大赛开始和结束时间为第一个和最后一个阶段的时间
            if (dto.getCompetitionStages() != null && !dto.getCompetitionStages().isEmpty()) {
                List<CompetitionStageDTO> stages = dto.getCompetitionStages();
                contest.setStartTime(stages.get(0).getStartTime());
                contest.setEndTime(stages.get(stages.size() - 1).getEndTime());
            }

            JsonNode competitionDesc = dto.getBasicInfo().getCompetitionDesc() != null
                    ? objectMapper.valueToTree(dto.getBasicInfo().getCompetitionDesc())
                    : objectMapper.createObjectNode();
            contest.setCompetitionDesc(competitionDesc);

            contest.setLogoUrl(dto.getBasicInfo().getLogoUrl());
            contest.setOrganizationHostname(dto.getOrganizationHostname());
            contest.setUpdateBy(LoginHelper.getUsername());
            

            // 更新大赛基本信息
            contestMapper.updateContest(contest);

            // 删除原有关联信息
            competitionDetailMapper.deleteByCompetitionId(competitionId);
            competitionStageMapper.deleteByCompetitionId(competitionId);
            competitionAttachmentMapper.deleteByCompetitionId(competitionId);

            // 重新保存关联信息
            saveCompetitionRelatedInfo(competitionId, dto);

            return AjaxResult.success("大赛更新成功");
        } catch (Exception e) {
            log.error("大赛更新失败", e);
            return AjaxResult.error("大赛更新失败: " + e.getMessage());
        }
    }

    @Override
    public List<CompetitionStage> getCompetitionStages(Long competitionId) {
        return competitionStageMapper.selectCompetitionStagesByCompetitionId(competitionId);
    }


    /**
     * 删除大赛信息
     */
    /**
     * 根据ID删除比赛信息
     *
     * @param id 比赛ID
     * @return 删除的记录数
     * @throws Exception 如果删除过程中出现异常，则抛出异常
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public int deleteContestById(Long id) {
        // 先删除关联数据
        competitionAttachmentMapper.deleteByCompetitionId(id);
        competitionStageMapper.deleteByCompetitionId(id);
        competitionDetailMapper.deleteByCompetitionId(id);
        
        // 最后删除大赛主表数据
        return contestMapper.deleteContestById(id);
    }

    /**
     * 批量删除大赛
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public int deleteContestByIds(Long[] ids) {
        for (Long id : ids) {
            // 先删除关联数据
            competitionAttachmentMapper.deleteByCompetitionId(id);
            competitionStageMapper.deleteByCompetitionId(id);
            competitionDetailMapper.deleteByCompetitionId(id);
        }
        // 最后批量删除大赛主表数据
        return contestMapper.deleteContestByIds(ids);
    }

    /**
     * 创建大赛(完整信息)
     */
    /**
     * 保存大赛关联信息
     */
    private void saveCompetitionRelatedInfo(Long competitionId, CompetitionCreateDTO dto) throws Exception {
        ObjectMapper objectMapper = new ObjectMapper();
        
        // 保存大赛详情
        CompetitionDetail detail = new CompetitionDetail();
        detail.setCompetitionId(competitionId);
        detail.setDetails(objectMapper.valueToTree(dto.getDetails()));
        competitionDetailMapper.insertCompetitionDetail(detail);

        // 保存比赛阶段信息
        if (dto.getCompetitionStages() != null && !dto.getCompetitionStages().isEmpty()) {
            List<CompetitionStage> stages = dto.getCompetitionStages().stream()
                .map(stageDTO -> {
                    CompetitionStage stage = new CompetitionStage();
                    stage.setCompetitionId(competitionId);
                    stage.setStageName(stageDTO.getStage());
                    stage.setStartTime(stageDTO.getStartTime());
                    stage.setEndTime(stageDTO.getEndTime());
                    stage.setCreateTime(new Date());
                    return stage;
                })
                .collect(Collectors.toList());
            competitionStageMapper.batchInsertCompetitionStages(stages);
        }

        // 保存附件信息
        if (dto.getAttachments() != null && !dto.getAttachments().isEmpty()) {
            List<CompetitionAttachment> attachments = dto.getAttachments().stream()
                .map(attachmentDTO -> {
                    CompetitionAttachment attachment = new CompetitionAttachment();
                    attachment.setCompetitionId(competitionId);
                    attachment.setFileName(attachmentDTO.getFileName());
                    attachment.setFileType(attachmentDTO.getFileType());
                    attachment.setFileSize(attachmentDTO.getFileSize());
                    attachment.setFileUrl(attachmentDTO.getFileUrl());
                    attachment.setDescription(attachmentDTO.getDescription());
                    attachment.setUpdateBy(LoginHelper.getUserId());
                    return attachment;
                })
                .collect(Collectors.toList());
            competitionAttachmentMapper.batchInsertCompetitionAttachments(attachments);
        }
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public AjaxResult createCompetition(CompetitionCreateDTO dto) {
        try {
            log.info("开始创建大赛，请求参数: {}", new ObjectMapper().writeValueAsString(dto));
            
            // 参数校验
            if (StringUtils.isBlank(dto.getBasicInfo().getName())) {
                throw new IllegalArgumentException("大赛名称不能为空");
            }

            // 设置大赛基本信息
            Contest contest = new Contest();
            contest.setName(dto.getBasicInfo().getName());
            contest.setTheme(dto.getBasicInfo().getTheme());
            contest.setType(dto.getBasicInfo().getType());
            contest.setOrganizationHostname(dto.getOrganizationHostname());
            contest.setTenantId(LoginHelper.getTenantId());
            
            // 设置大赛开始和结束时间为第一个和最后一个阶段的时间
            if (dto.getCompetitionStages() != null && !dto.getCompetitionStages().isEmpty()) {
                List<CompetitionStageDTO> stages = dto.getCompetitionStages();
                contest.setStartTime(stages.get(0).getStartTime());
                contest.setEndTime(stages.get(stages.size() - 1).getEndTime());
            }
            
            ObjectMapper objectMapper = new ObjectMapper();
            JsonNode competitionDesc = dto.getBasicInfo().getCompetitionDesc() != null 
                ? objectMapper.valueToTree(dto.getBasicInfo().getCompetitionDesc())
                : objectMapper.createObjectNode();
            contest.setCompetitionDesc(competitionDesc);
            contest.setLogoUrl(dto.getBasicInfo().getLogoUrl());
            contest.setCreateBy(LoginHelper.getUsername());

            // 保存大赛基本信息
            int result = contestMapper.insertContest(contest);
            if (result <= 0) {
                throw new RuntimeException("大赛基本信息保存失败");
            }
            Long competitionId = contest.getId();

            // 保存关联信息
            saveCompetitionRelatedInfo(competitionId, dto);

            return AjaxResult.success("大赛创建成功", competitionId);
        } catch (IllegalArgumentException e) {
            log.error("参数校验失败: {}", e.getMessage());
            return AjaxResult.error(e.getMessage());
        } catch (Exception e) {
            log.error("大赛创建失败", e);
            return AjaxResult.error("大赛创建失败: " + e.getMessage());
        }
    }
}